#!/usr/bin/python
import kgconfig

#TODO: befor mirror scan rls diractory has 'DONE'
#TODO: after working done mark a tag in rls directory 'DONE'
#TODO: Scan pre today rls

from glob import glob
from kgconfig import *
from shutil import rmtree 
from string import lower, upper
import datetime
import os
import os.path
import re
import sys
import traceback

__version__ = '0.0.5'

DEBUGTOGGLE = kgconfig.SHOWDEBUG 
def show_debug( *values ):
    if DEBUGTOGGLE == 0: return
    print >> sys.stderr, "DBG>", 
    for v in values: print >> sys.stderr, v, 
    print >> sys.stderr, '.'


#clean Old file or temp file
find_rls_script = 'find_rls_script'
found_zwt_kg_rls = 'found_zwt_kg_rls'
mirror_queue_script = 'mirror_queue_script'  
upload_queue_script = 'upload_queue_script' 

def doInitClean():
    '''
    '''
    
    try:
        os.remove( os.path.join( WORK_DIR, find_rls_script ) ) 
        show_debug( 'Remove File Succeed: find_rls_script' )
    except OSError, ( errno, strerror ):
        show_debug( 'Remove File Error from OSError(%s), find_rls_script %s ' %  ( errno, strerror ) )
        
    try:
        os.remove( os.path.join( WORK_DIR, found_zwt_kg_rls ) ) 
        show_debug( 'Remove File Succeed: found_today_zwt_kg_rls' )
    except OSError, ( errno, strerror ):
        show_debug( 'Remove File Error from OSError(%s), found_today_zwt_kg_rls  %s ' %  ( errno, strerror ) )
        
    try:
        os.remove( os.path.join( WORK_DIR, mirror_queue_script ) ) 
        show_debug( 'Remove File Succeed: mirror_queue_script' ) 
    except OSError, ( errno, strerror ):
        show_debug( 'Remove File Error from OSError(%s), mirror_queue_script %s ' %  ( errno, strerror ) )
        
    try:
        os.remove( os.path.join( WORK_DIR, upload_queue_script ) ) 
        show_debug( 'Remove File Succeed: upload_queue_script' )
    except OSError, ( errno, strerror ):
        show_debug( 'Remove File Error from OSError(%s), upload_queue_script %s ' %  ( errno, strerror ) )
    return
        
def doCheckRunninig():
    '''check job is running ?'''
    
    if os.path.isfile( os.path.join( WORK_DIR, 'now_progress' ) ):
        #program running exit
        show_debug( "Found 'now_progress' File, Must exit now. Error(1).\nIf you know what you do , del now_progress file in directory" )
        return 1 # has Program running ,return 1
    else:
        return 0 # Ready to run
    
def doMarkRunning():
    '''When program is running , make a tag'''
    try :
        fp = open( os.path.join( WORK_DIR, 'now_progress' ), 'w' )
        fp.close()
    except IOError, ( errno, strerror ):
        show_debug( "Make progress_file Error(%s): %s" % ( errno, strerror ) )
        return errno
    return 0 # Succeed


def doExitClean():
    '''when job finish , try to clean tag
    '''

    try:
        os.remove( os.path.join( WORK_DIR, 'now_progress' ) )
    except IOError, ( errno, strerror ):
        show_debug( "Clean progress_file Error(%s): %s" % ( errno, strerror ) )
        return errno
    return 0 # Succeed
    
def make_find_rls_script():
    ''' This functions is open ftp server and find all ZWT rls, then make a lftp script
    '''
    
    #TODO:  Error manage
    lftp_bookmark = "bookmark add C3 %s/\n" % FTP_C3 
    lftp_open = "o C3\n"
    lftp_cd_to_oday = "cd /0day/\n"
    lftp_find_zwt_kg_rls = '''find -d 2 %s/ > found_today_zwt_kg_rls \n''' % today
    lftp_quit = "quit\n"
    try:
        fp = open( os.path.join( WORK_DIR, find_rls_script ), 'w' )
        fp.write( lftp_bookmark )
        fp.write( lftp_open )
        fp.write( lftp_cd_to_oday )
        fp.write( lftp_find_zwt_kg_rls )
        fp.write( lftp_quit )
        fp.flush()
	fp.close()
    except IOError, ( errno, strerr ):
        show_debug( "Make 'find_rls_script' Error(%s): %s" % ( errno, strerr ) )
        return errno
    return 0 #Succeed
    
def make_mirror_queue_script( mirror_lists ):
    #TODO: check Local rls list ,if not ,add it to mirror_queue_script, else do nothing ,Finish
    #build a list ,save mirror job rls name in it ,Finish
    mirror_jobs = []
    local_rls_lists = os.listdir( os.path.join( WORK_DIR, RLS_LIST_DIR ) )
    lftp_quit = "quit\n"
    fp = open( os.path.join( WORK_DIR, mirror_queue_script ), 'w' )
    for x in mirror_lists:
        #print x
        if FORCE_MIRROR:
            fp.write( 'mirror -c --parallel=2 %s%s%s %s\n' % ( FTP_C3, ODAY, x[0], os.path.join( RLS_LIST_DIR, x[1] ) ) )
            mirror_jobs.append( x[1] )
        else :
            if x[1] not in local_rls_lists :
                fp.write( 'mirror -c --parallel=2 %s%s%s %s\n' % ( FTP_C3, ODAY, x[0], os.path.join( RLS_LIST_DIR, x[1] ) ) )
                mirror_jobs.append( x[1] )
            else:
                pass 
    fp.write( lftp_quit )
    fp.flush()
    fp.close()
    return mirror_jobs
    
def isDone():
    pass
    
def markDone():
    pass
    
    
def oper_time( day_ago ):
    '''date function
    
    @param day_ago:
    '''
    
    dates = []
    current_time = datetime.datetime.now()

    for x in range( 1, day_ago ) :
        day_ago = current_time + datetime.timedelta( days=-x )
        dates.append( day_ago.strftime( '%m%d' ) )
	            
    return dates

def make_upload_queue_script( rls_jobs , kg_lists ):
    '''
    cd x
    mkdir rls _name
    cd rls_name
    lcd rls_dir
    put kg
    put zwt.nfo
    cd ..
    cd ..
    
    @param rls_jobs:
    @param kg_lists:
    '''

    fp = open( os.path.join( WORK_DIR, upload_queue_script ), 'w' )
    lftp_bookmark = "bookmark add C3 %s/\n" % FTP_C3 
    lftp_open = "o C3\n"
    lftp_cd_kg_archive = "cd %s\n" % KG_ARCHIVE
    fp.write( lftp_bookmark )
    fp.write( lftp_open )
    fp.write( lftp_cd_kg_archive )
    
    for x in rls_jobs:
        fp.write( "cd %s \n" % os.path.join( KG_ARCHIVE, upper( str( x[0] ) ) ) )
        fp.write( "mkdir %s \n" % x )
	fp.write( "cd %s \n" % x ) 
	fp.write( "lcd %s \n" % os.path.join( WORK_DIR, RLS_LIST_DIR, x ) )
        upload_files =  os.listdir( os.path.join( WORK_DIR, RLS_LIST_DIR, x ) )
        for y in upload_files :
            fp.write( "put %s \n" % y )
	#fp.write( "put zwt.nfo\n")
        fp.write( "cd ..\n" )
	fp.write( "cd .. \n" )
        fp.write( "lcd ..\n" )
        
    lftp_quit = "quit\n"
    fp.write( lftp_quit )
    fp.flush()
    fp.close
    
def do_lftp_script( script_name ):
    exec_lftp_comand = LFTP_DIR+" %s -f %s" % ( LFTP_DEBUG, os.path.join( './', script_name ) ) 
    #print exec_lftp_comand
    #ex_code = os.spawnl( os.P_WAIT, LFTP_DIR , exec_lftp_comand )
    ex_code = os.system( exec_lftp_comand )
    if ex_code !=0:
        show_debug( "Run lftp Error(%s): %s" % ( ex_code, exec_lftp_comand ) )
    elif ex_code == 0:
        show_debug( "Run lftp Succeed(%s) : %s" % ( ex_code, exec_lftp_comand ) )
    return ex_code
    #0 succeed, other Error
    
    
def do_analyse_found_today_zwt_kg_rls():
    zwt_kg_rls_rec = re.compile( r"""[a-zA-Z0-9\.\-\_]*[kK]eymaker[a-zA-Z0-9\.\-\_]*\-ZWT$""" )
    zwt_kg_rls_incomplete_rec= re.compile( r"""^\(incomplete\)[a-zA-Z0-9\.\-\_]*[kK]eymaker[a-zA-Z0-9\.\-\_]*\-ZWT$""" )
    incomplete_rec = re.compile( r"""^\(incomplete\)\-""" )
    try:
        fp = open( os.path.join( WORK_DIR, found_zwt_kg_rls ), 'r' )
        all_rls_names = fp.readlines()
        fp.close()
    except IOError, ( errno, strerror ):
        show_debug( "I/O error(%s): %s %s" % ( errno, os.path.join( WORK_DIR, found_zwt_kg_rls ), strerror, ) )
        sys.exit( 1 )
    mirror_lists = []
    for x in all_rls_names:
        for y in x.split( '/' ):
            if zwt_kg_rls_rec.search( y ):
                if not zwt_kg_rls_incomplete_rec.search( y ):
                    mirror_lists.append( ( x.rstrip(), y.rstrip() ) ) #TODO: remove incomplete rls from  all_rls_names
                else:
                    pass # Found incomplete rls
    return mirror_lists
    
#~ def do_unzip_rls( job_lists ):
    #~ for x in job_lists:
        #~ rls_path = os.path.join( WORK_DIR, RLS_LIST_DIR, x )
        #~ for y in glob( os.path.join( rls_path, '*.zip' ) ):
            #~ unzip_command = '%s -o %s -d %s/temp/' % ( UNZIP_DIR, y, os.path.join( WORK_DIR, RLS_LIST_DIR, x ) )
            #~ ex_code = os.spawnl( os.P_WAIT, UNZIP_DIR , unzip_command )
            #~ if ex_code != 0:
                #~ do_unzip_err( y, ex_code )
    #~ return
            
#~ def do_unrar_rls( job_lists ):
    #~ for x in job_lists:
        #~ #print x,WORK_DIR, RLS_LIST_DIR
        #~ rls_path = os.path.join( WORK_DIR, RLS_LIST_DIR, x , 'temp' )
        #~ print rls_path
        #~ for y in glob( os.path.join( rls_path, '*.rar' ) ):
            #~ print y
            
def do_unzip_rls2( rls_name ):
    try:
	rls_path = os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name )
	for y in glob( os.path.join( rls_path, '*.zip' ) ):
    	    unzip_command = '%s -o %s -d %s/temp/ > /dev/null' % ( UNZIP_DIR, y, os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name ) )
    	    #ex_code = os.spawnl( os.P_WAIT, UNZIP_DIR , unzip_command )
    	    ex_code = os.system( unzip_command ) 
	    if ex_code != 0:
        	do_unzip_err( y, ex_code )
    	    else:
        	pass #succeed
	return 0 
    except:
	print >> sys.stderr, "Unzip %s unknow Error" % rls_name
    
def do_unrar_rls2( rls_name ):
    rls_path_temp = os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name , 'temp' )
    # only unrar first rar file zwt.rar, zwt.part1.rar
    try:
	unrar_command = "%s x %s  -x ?eygen*.* -inul -ierr -o+ %s > /dev/null" % \
	    ( UNRAR_DIR, glob( os.path.join( rls_path_temp, '*.rar' ) )[0], os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name ) )
	#ex_code = os.spawnl( os.P_WAIT, UNRAR_DIR , unrar_command )
	ex_code = os.system ( unrar_command )
	if ex_code !=0 :
    	    do_unrar_err( rls_name, ex_code )
	else:
    	    pass# succeed
	return 0
    except:
	show_debug( "Unrar %s unknow Error" % rls_name )
	        
def do_rename_kg( rls_name ):
    """rename keygen, and clean rls directory,only keep keygen file"""
    
    kg_lists = glob( os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name, '*eygen*.*' ) )
    if len( kg_lists ) == 0:
	show_debug( "Error Not Found keygen in %s" % rls_name )
	return
    else:
	pass
    for x in kg_lists:
        keygen_rename = rls_kg_rec.sub( rls_name, x, 1 )
        try:
            os.rename( x, keygen_rename )
            #fix_kg_lists.append(keygen_rename)
        except OSError, ( errno, strerror ):
            show_debug( "Rename Error(%s) %s -> %s : %s" %  ( errno, x, keygen_rename, strerror ) )
        fix_kg_lists.append( keygen_rename )
        #print keygen_rename
        
    #List All File in rls dir
    all_lists_in_rls = glob( os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name, '*' ) )
    do_clean_rls( rls_name, all_lists_in_rls, fix_kg_lists )
    
def do_clean_rls( rls_name, all_lists_in_rls, kg_lists ):
    #List All File in rls dir
    #print all_lists_in_rls
    nfo = "zwt.nfo"
    for x in kg_lists:
        if x in all_lists_in_rls:
            #print 'Yes', x
            del all_lists_in_rls[all_lists_in_rls.index( x )]
	else :
            pass
    
    # do not del 'zwt.nfo' file
    try:	    
	del all_lists_in_rls[all_lists_in_rls.index( os.path.join( WORK_DIR, RLS_LIST_DIR, rls_name, nfo ) )]
    except ValueError:
	show_debug( "Not Found zwt.nfo File" )
    
    #print os.path.join(WORK_DIR,RLS_LIST_DIR,rls_name,nfo)
    #print all_lists_in_rls
    for x in all_lists_in_rls:
        if os.path.isfile( x ):
            os.remove( x )
        elif os.path.isdir( x ):
            rmtree( x, ignore_errors=True )
        else:
            pass
            
def do_unzip_err( rls_path, err_code=65535 ):
    show_debug( 'Error: Unzip %s Error, exit code %s ' % ( rls_path, str( err_code ) ) )
    return err_code

def do_unrar_err( rls_path, err_code=65535 ):
    show_debug( 'Error: Unrar %s Error, exit code %s ' % ( rls_path, str( err_code ) ) )
    return err_code
    
def main():
    
    
    if doCheckRunninig() != 0 :
        #last time program running , must exit this job
        #does not need clean
        sys.exit( 1 )
    else:
        pass
        
    if doMarkRunning() != 0 :
        #Marking progress_file Error
        #does not need clean
        sys.exit( 1 )
    else:
        pass
        
    doInitClean()
    
    if make_find_rls_script() != 0 :
        #make fine_rls_script Error exit
        doExitClean()
        sys.exit( 1 )
    else:
        pass
    
    if do_lftp_script( find_rls_script ) != 0:
        show_debug( "Do lftp Script Error(126)" )
        doExitClean()
        sys.exit( 126 ) # 126 means lftp Script  find_rls_script Error
    else :
        pass
    rlss =  do_analyse_found_today_zwt_kg_rls()
    rls_jobs = make_mirror_queue_script( rlss )
    if do_lftp_script( mirror_queue_script ) != 0 :
        show_debug( "Do lftp Script Error(125)" )
        doExitClean()
        sys.exit( 125 ) # 125 means lftp Script  mirror_queue_script Error
    else :
        pass
    
    # Unzip Unrar rename rls
    global rls_kg_rec
    rls_kg_rec = re.compile( "[kK]?eygen" )
    global fix_kg_lists
    fix_kg_lists = []
    for x in rls_jobs:
        do_unzip_rls2( x )
        do_unrar_rls2( x )
        do_rename_kg( x )
        #do_clean_rls( x )
        
    make_upload_queue_script( rls_jobs, fix_kg_lists )    
    
    if do_lftp_script( upload_queue_script ) != 0:
        show_debug( "Do lftp Script Error(124)" )
        doExitClean()
        sys.exit( 124 ) # 124 means lftp Script  upload_queue_script Error
    else :
        pass
        
    doExitClean()
    
        
if __name__ == '__main__':
    try:
	main()
    except:
	f = open( 'Error.log', 'a' )
	traceback.print_exc( file=f )
	f.flush()
	f.close()
